Do not create blkback vbd kernel thread until fully connected
authorkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Thu, 6 Apr 2006 17:39:00 +0000 (18:39 +0100)
committerkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Thu, 6 Apr 2006 17:39:00 +0000 (18:39 +0100)
to frontend driver. Otherwise the kernel thread may crash trying
to access the non-existent shared ring.

Signed-off-by: Keir Fraser <keir@xensource.com>
linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c
linux-2.6-xen-sparse/drivers/xen/blkback/common.h
linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c

index 4faf1170697298cbf5c818dda01f96cf3c5fcf0f..fe2367a8fc94eeddf70f29d2455565d864c3b21c 100644 (file)
@@ -287,7 +287,7 @@ static int end_block_io_op(struct bio *bio, unsigned int done, int error)
  * NOTIFICATION FROM GUEST OS.
  */
 
-void blkif_notify_work(blkif_t *blkif)
+static void blkif_notify_work(blkif_t *blkif)
 {
        blkif->waiting_reqs = 1;
        wake_up(&blkif->wq);
index 58939d6ab2f4ff92e3b706e4e6fd093cddab02f3..a32466e3a793e8776891034f7664b831f2a12e90 100644 (file)
@@ -129,7 +129,6 @@ void blkif_interface_init(void);
 
 void blkif_xenbus_init(void);
 
-void blkif_notify_work(blkif_t *blkif);
 irqreturn_t blkif_be_int(int irq, void *dev_id, struct pt_regs *regs);
 int blkif_schedule(void *arg);
 
index d0ec094d66e0a975bff80b376116c183d7a46881..011bec8d19a6c69ea0ebb0219305a46f2ac4d0f1 100644 (file)
@@ -46,10 +46,29 @@ static void backend_changed(struct xenbus_watch *, const char **,
 
 static void update_blkif_status(blkif_t *blkif)
 { 
-       if (blkif->irq && blkif->vbd.bdev &&
-           (blkif->be->dev->state != XenbusStateConnected)) {
-               connect(blkif->be);
-               blkif_notify_work(blkif);
+       int err;
+
+       /* Not ready to connect? */
+       if (!blkif->irq || !blkif->vbd.bdev)
+               return;
+
+       /* Already connected? */
+       if (blkif->be->dev->state == XenbusStateConnected)
+               return;
+
+       /* Attempt to connect: exit if we fail to. */
+       connect(blkif->be);
+       if (blkif->be->dev->state != XenbusStateConnected)
+               return;
+
+       blkif->xenblkd = kthread_run(blkif_schedule, blkif,
+                                    "xvd %d %02x:%02x",
+                                    blkif->domid,
+                                    blkif->be->major, blkif->be->minor);
+       if (IS_ERR(blkif->xenblkd)) {
+               err = PTR_ERR(blkif->xenblkd);
+               blkif->xenblkd = NULL;
+               xenbus_dev_error(blkif->be->dev, err, "start xenblkd");
        }
 }
 
@@ -215,17 +234,6 @@ static void backend_changed(struct xenbus_watch *watch,
                        return;
                }
 
-               be->blkif->xenblkd = kthread_run(blkif_schedule, be->blkif,
-                                                "xvd %d %02x:%02x",
-                                                be->blkif->domid,
-                                                be->major, be->minor);
-               if (IS_ERR(be->blkif->xenblkd)) {
-                       err = PTR_ERR(be->blkif->xenblkd);
-                       be->blkif->xenblkd = NULL;
-                       xenbus_dev_error(dev, err, "start xenblkd");
-                       return;
-               }
-
                device_create_file(&dev->dev, &dev_attr_physical_device);
                device_create_file(&dev->dev, &dev_attr_mode);